package com.starview.star.compiler.cafe.compile.cont;

import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TypeInsnNode;

import com.starview.platform.data.type.Location;
import com.starview.star.compiler.ErrorReport;
import com.starview.star.compiler.cafe.compile.CafeDictionary;
import com.starview.star.compiler.cafe.compile.CodeContext;
import com.starview.star.compiler.cafe.compile.ISpec;
import com.starview.star.compiler.cafe.compile.SrcSpec;
import com.starview.star.compiler.cafe.compile.Types;

public class ThrowContinuation implements IContinuation
{
  private final String msg;

  public ThrowContinuation(String msg)
  {
    this.msg = msg;
  }

  @Override
  public ISpec cont(ISpec src, CafeDictionary cxt, Location loc, ErrorReport errors, CodeContext ccxt)
  {
    MethodNode mtd = ccxt.getMtd();
    InsnList ins = mtd.instructions;

    ins.add(new TypeInsnNode(Opcodes.NEW, Types.EVALUATION_EXCEPTION));
    ins.add(new InsnNode(Opcodes.DUP));
    ins.add(new LdcInsnNode(msg));
    ins.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, Types.EVALUATION_EXCEPTION, Types.INIT, "("
        + Types.JAVA_STRING_SIG + ")V"));
    ins.add(new InsnNode(Opcodes.ATHROW));
    return SrcSpec.prcSrc;
  }

  @Override
  public boolean isJump()
  {
    return true;
  }

}
